github_qr_code()
submit choice Burj Khalifa - Dubai¶App.box_*() APIApp.box_create(name, size) - any size ($\leq$ 32KB)¶App.box_length(name) - opcode box_len¶App.box_delete(name) - opcode box_del¶App.box_replace(name, idx, L) - set part of box¶App.box_extract(name, idx, L) - get part of box¶App.box_put(name, value) - set value (may create box)¶App.box_get(name) - get everything (fail if size > 4KB)¶App.box_get() and App.box_put()¶from pyteal import Int, Itob, Txn, App, Seq, If, Assert, Btoi
# App.box: account --> choice
# App.global: choice --> count
num_choices = Int(7)
choice = Itob(Int(1)) # index for "Burj Khalifa - Dubai"
box_key = Txn.sender() # sender's account
previous = App.box_get(box_key) # MaybeValue
submit_expr = Seq(
Assert(Btoi(choice) < num_choices),
If(previous.hasValue()).Then(
App.globalPut( # App.global[previous] -= 1 :
previous.value(),
App.globalGet(previous.value()) - Int(1)
),
),
App.box_put(box_key, choice), # App.box[box_key] <-- choice
# App.global[choice] += 1 :
App.globalPut(choice, App.globalGet(choice) + Int(1)),
)
methods - allow interacting with Poll App¶delete for reasons to be explained shortly)¶OnComplete Actions for App Transactions¶Router and its M.O.E. Questions¶moe()
Router and its M.O.E. Questions¶Router constructs the Teal code necessary to delegate application transactions to either a bare app call action or a method based on answers to:¶bare app call? If not, which method selected?¶OnComplete is requested?¶exists? (Conversely, being created?)¶Router Initialization¶warning()
# WARNING: STUBS ARE FOR ROUTER-ILLUSTRATION PURPOSES ONLY!!!
del_action = OnCompleteAction.call_only(Seq())
router = Router(
name="OpenPollingApp",
descr="This is a polling application.",
bare_calls=BareCallActions(delete_application=del_action),
)
approval, clear, json_contract = router.compile_program(version=8)
JSON Contract (with no methods)¶print(json.dumps(json_contract.dictify(), indent=2))
{
"name": "OpenPollingApp",
"methods": [],
"networks": {},
"desc": "This is a polling application."
}
approval, clear, json_contract = router.compile_program(version=8)
print(approval)
#pragma version 8 txn NumAppArgs int 0 == bnz main_l2 err main_l2: txn OnCompletion int DeleteApplication == bnz main_l4 err main_l4: txn ApplicationID int 0 != assert int 1 return
delete¶show() # custom method showing relevant Teal
txn NumAppArgs
int 0
==
bnz main_l2
. . .
main_l2:
txn OnCompletion
int DeleteApplication
==
bnz main_l4
. . .
main_l4:
txn ApplicationID
int 0
!=
assert
int 1
return
methods to route with @router.method¶open() and close()¶@router.method(name="open")
def open_poll() -> Expr:
"""Marks this poll as open."""
return Seq()
@router.method(name="close")
def close_poll() -> Expr:
"""Marks this poll as closed."""
return Seq()
warning()
approval, clear, json_contract = router.compile_program(version=8)
print(json.dumps(json_contract.dictify(), indent=2))
{
"name": "OpenPollingApp",
"methods": [
{
"name": "open",
"args": [],
"returns": {
"type": "void"
},
"desc": "Marks this poll as open."
},
{
"name": "close",
"args": [],
"returns": {
"type": "void"
},
"desc": "Marks this poll as closed."
}
],
"networks": {},
"desc": "This is a polling application."
}
PyTeal Type |
ARC-4 Type |
Dynamic / Static |
Description |
|---|---|---|---|
|
Static |
An 8-bit unsigned integer |
|
|
IFF |
A fixed-length array with N elements |
|
|
Dynamic |
Variable-length byte array |
@router.method
def submit(choice: abi.Uint8) -> Expr:
"""Submit a response to the poll.
Args:
choice: The choice made by the sender.
"""
return Seq()
warning()
opts = OptimizeOptions(scratch_slots=True)
(approval, clear, json_contract) = \
router.compile_program(version=8, optimize=opts)
# ------------------------------------^^^^^^^^^^^^^
submit(choice) portion of JSON contract¶show() # lines 20-33 of the JSON contract
{
"name": "submit",
"args": [
{
"type": "uint8",
"name": "choice",
"desc": "The choice made by the sender."
}
],
"returns": {
"type": "void"
},
"desc": "Submit a response to the poll."
}
submit(choice)¶show()
txna ApplicationArgs 0
method "submit(uint8)void"
==
bnz main_l5
. . .
main_l5:
txn OnCompletion
int NoOp
==
txn ApplicationID
int 0
!=
&&
assert
txna ApplicationArgs 1
int 0
getbyte
callsub submit_2
. . .
// submit
submit_2:
store 0
retsub
contract/contract.py¶show()
contract/contract.json¶show()
contract/approval.teal¶show()
demo_qr_code()
Property |
Global Storage |
Local Storage |
Box Storage |
|---|---|---|---|
| Max(key+value) | 128 bytes | 128 bytes | 32,832 bytes |
| Max storage | 64 pairs or 8 KB | 16 pairs or 2 KB | $\infty$ |
| On-Chain Visibility | Public | Public | Private: boxes only visible to their app |
| Best Case MBR* | 0.40 Algo/KB | 0.40 Algo/KB | 0.41 Algo/KB |
| Account for MBR | Creator Account | Opt-In Account | App Account |
| MBR funds after app deletion | Recovered | CloseOut to recover | Unrecoverable ** |
| External Ref in Txn | Appid for external lookup | Appid + creator acct for external lookup | Box reference required |